Current Sprint: 1. 完成 HappyPath: 可以建立一場遊戲,玩到結束
repo: https://github.com/side-project-at-SPT/ithome-ironman-2024-san-juan
swagger docs: https://side-project-at-spt.github.io/ithome-ironman-2024-san-juan/
昨天開了專案,並把服務上線
今天把 rspec & swagger 裝起來
api 開發完成後,可以用 swagger 文件的方式分享給其他成員串接,而套件 rswag 提供了從 spec 生成 swagger 的能力,讓你寫測試時同時寫好 swagger docs。
$ bundle add rspec-rails
# Generate boilerplate configuration files
# (check the comments in each generated file for more information)
$ rails generate rspec:install
# create .rspec
# create spec
# create spec/spec_helper.rb
# create spec/rails_helper.rb
$ bundle add rswag
$ rails g rswag:install
# generate rswag:specs:install
# rails generate rswag:specs:install
# create spec/swagger_helper.rb
# generate rswag:api:install
# rails generate rswag:api:install
# create config/initializers/rswag_api.rb
# route mount Rswag::Api::Engine => '/api-docs'
# generate rswag:ui:install
# rails generate rswag:ui:install
# create config/initializers/rswag_ui.rb
# route mount Rswag::Ui::Engine => '/api-docs'
$ rails rswag
# Generating Swagger docs ...
# No examples found.
# Swagger doc generated at /your-repo-root/swagger/v1/swagger.yaml
# Finished in 0.00004 seconds (files took 0.71248 seconds to load)
# 0 examples, 0 failures
開啟 server 後,訪問 http://localhost:3000/api-docs/index.html 看看吧
DEPRECATION WARNING: Rswag::Ui: WARNING: The method will be renamed to "openapi_endpoint" in v3.0
# /config/initializers/rswag_ui.rb:11
Rswag::Ui.configure do |c|
...
- c.swagger_endpoint "/api-docs/v1/swagger.yaml", "API V1 Docs"
+ c.openapi_endpoint "/api-docs/v1/swagger.yaml", "API V1 Docs"
...
end
新增產生 swagger docs CI,將 swagger 部署在 GitHub page
執行產生 swagger docs CI 時,略過檢查
# /spec/rails_helper.rb:31
...
begin
- ActiveRecord::Migration.maintain_test_schema!
+ ActiveRecord::Migration.maintain_test_schema! unless ENV.fetch("API_DOC_MODE", nil)
rescue ActiveRecord::PendingMigrationError => e
abort e.to_s.strip
end
...
設定 swagger config
# at /spec/swagger_helper.rb
# frozen_string_literal: true
require 'rails_helper'
RSpec.configure do |config|
# Specify a root folder where Swagger JSON files are generated
# NOTE: If you're using the rswag-api to serve API descriptions, you'll need
# to ensure that it's configured to serve Swagger from the same folder
config.openapi_root = Rails.root.join('swagger').to_s
# Define one or more Swagger documents and provide global metadata for each one
# When you run the 'rswag:specs:swaggerize' rake task, the complete Swagger will
# be generated at the provided relative path under openapi_root
# By default, the operations defined in spec files are added to the first
# document below. You can override this behavior by adding a openapi_spec tag to the
# the root example_group in your specs, e.g. describe '...', openapi_spec: 'v2/swagger.json'
config.openapi_specs = {
'v1/swagger.yaml' => {
openapi: '3.0.1',
info: {
title: 'API V1',
version: 'v1'
},
paths: {},
servers: [
{
url: 'http://localhost:3000',
description: 'Development environment'
},
{
url: 'https://ithome-ironman-2024-san-juan.zeabur.app/', # 改成你的 domain name
description: 'Production environment at Zeabur'
}
]
}
}
# Specify the format of the output Swagger file when running 'rswag:specs:swaggerize'.
# The openapi_specs configuration option has the filename including format in
# the key, this may want to be changed to avoid putting yaml in json files.
# Defaults to json. Accepts ':json' and ':yaml'.
config.openapi_format = :yaml
end
把 gen 好的 html 放在 public/ (手動 SSG)
至 GitHub repo Settings > Pages > Build and deployment Source 選 GitHub Actions
現在推 code 之後,可以在 https://your-account.github.io/reop-name/ 看到 swagger
接下來新增一個簡單的 endpoint
$ rails g controller walking_skeleton
# create app/controllers/walking_skeleton_controller.rb
# invoke rspec
# create spec/requests/walking_skeleton_spec.rb
# spec/requests/walking_skeleton_spec.rb
require 'swagger_helper'
RSpec.describe 'WalkingSkeleton', type: :request do
path '/walking-skeleton' do
get 'Examine the walking skeleton' do
tags 'Walking Skeleton'
produces 'application/json'
response '200', 'Walk' do
schema type: :object,
properties: {
message: { type: :string }
},
required: [ 'message' ]
run_test!
end
end
end
end
接受所有 method 的請求
# config/routes.rb
Rails.application.routes.draw do
# ...
match "walking-skeleton", to: "walking_skeleton#show", via: :all
# ...
end
# app/controllers/walking_skeleton_controller.rb
class WalkingSkeletonController < ApplicationController
def show
respond_to do |format|
format.json { render json: { message: "Walk #{Time.current}" } }
format.html { render plain: "Server is up and running -- #{Time.current}" }
end
end
end
在 ApplicationController
新增 MimeResponds
的功能
# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include ActionController::MimeResponds
end
$ rails rsawg
$ rails s
# swagger 的位置在 http://localhost/api-docs
成功
推上線後發現,送出請求時會遇到 CORS 錯誤
gem 註解拿掉,並執行 bundle install
# Gemfile:27
- # gem "rack-cors"
+ gem "rack-cors"
編輯 config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "*"
resource [ "/api/v1/*", "walking-skeleton" ],
headers: :any,
methods: [ :get, :post, :put, :patch, :delete, :options, :head ]
end
end
推送更新
完成啦
假日多存幾篇 XD
以上不代表明天會做,如有雷同純屬巧合
SPT (Side Project Taiwan) 的宗旨是藉由Side Project開發來成就自我,透過持續學習和合作,共同推動技術和專業的發展。我們相信每一個參與者,無論是什麼專業,都能在這個社群中找到屬於自己的成長空間。
歡迎所有對Side Project開發有興趣的人加入我們,可以是有點子來找夥伴,也可以是來尋找有興趣的Side Project加入,邀請大家一同打造一個充滿活力且有意義的技術社群!
Discord頻道連結:https://sideproj.tw/dc